///
///	@file 	httpComp.cpp
/// @brief 	Compile files and web pages and documents into C++ source.
///	@overview Usage: httpComp -p prefix -r romName filelist >webrom.c
///	\n\n
///		Prefix is a string to be removed from the front of all file names.
///		RomName is the name of data structure to hold the compiled files.
///
/////////////////////////////////// Copyright //////////////////////////////////
//
//	@copy	default.g
//	
//	Copyright (c) Mbedthis Software LLC, 2003-2007. All Rights Reserved.
//	Portions Copyright (c) GoAhead Software, 1995-2000. All Rights Reserved.
//	
//	This software is distributed under commercial and open source licenses.
//	You may use the GPL open source license described below or you may acquire 
//	a commercial license from Mbedthis Software. You agree to be fully bound 
//	by the terms of either license. Consult the LICENSE.TXT distributed with 
//	this software for full details.
//	
//	This software is open source; you can redistribute it and/or modify it 
//	under the terms of the GNU General Public License as published by the 
//	Free Software Foundation; either version 2 of the License, or (at your 
//	option) any later version. See the GNU General Public License for more 
//	details at: http://www.mbedthis.com/downloads/gplLicense.html
//	
//	This program is distributed WITHOUT ANY WARRANTY; without even the 
//	implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
//	
//	This GPL license does NOT permit incorporating this software into 
//	proprietary programs. If you are unable to comply with the GPL, you must
//	acquire a commercial license to use this software. Commercial licenses 
//	for this software and support services are available from Mbedthis 
//	Software at http://www.mbedthis.com 
//	
//	@end
//
////////////////////////////////// Includes ////////////////////////////////////

#include	<fcntl.h>
#include	<stdio.h>
#include	<stdlib.h>
#include	<string.h>
#include	<sys/stat.h>
#include	<time.h>

#if WIN
#include	<io.h>
#define 	MPR_TEXT "t"
#else
#include	<unistd.h>
#define 	MPR_TEXT ""
#if !CYGWIN
#define 	O_BINARY 0
#endif
#endif
#if VXWORKS
#include	<ioLib.h>
#endif

#include	"posixRemap.h"

///////////////////////////// Forward Declarations /////////////////////////////

static void printUsage();
static int	binToC(char *files, char *romName, char *prefix);

//////////////////////////////////// Code //////////////////////////////////////
//
//	Main program
// 

int main(int argc, char *argv[])
{
	char	*prefix, *romName, *fileName, *cp;
	int		i, errflg;

	errflg = 0;
	prefix = "";
	romName = "defaultRomFiles";

	for (i = 1; i < argc && !errflg; i++) {
		if (argv[i][0] != '-') {
			break;
		}

		for (cp = &argv[i][1]; *cp && !errflg; cp++) {
			if (*cp == 'p') {
				if (++i == argc) {
					errflg++;
				} else {
					prefix = argv[i];
					break;
				}

			} else if (*cp == 'r') {
				if (++i == argc) {
					errflg++;
				} else {
					romName = argv[i];
					break;
				}
			}
		}
	}

	if (i > argc) {
		errflg++;
	}
	if (errflg) {
		printUsage();
		exit(2);
	}	
	fileName = argv[i];

	if (binToC(fileName, romName, prefix) < 0) {
		return -1;
	}
	return 0;
}

////////////////////////////////////////////////////////////////////////////////
//
//	Output usage message
 

static void printUsage()
{
	fprintf(stderr, 
		"usage: httpComp -p prefix -r romName filelist >output.cpp\n");
}

////////////////////////////////////////////////////////////////////////////////

/// 
///	Encode the files as C++ code
///

static int binToC(char *files, char *romName, char *prefix)
{
	struct stat		finfo;
	FILE			*fp;
	time_t			now;
	char			fileBuf[512], buf[512];
	char			*cp, *sl, *p, *timep;
	int				j, i, len, fd, nFile;

	if ((fp = fopen(files, "r")) == NULL) {
		fprintf(stderr, "Can't open file list %s\n", files);
		return -1;
	}

	printf("//\n//	romFiles.cpp -- Compiled Files\n//\n");
	time(&now);
	timep = ctime(&now);
	printf("//	GENERATED by httpComp on %s \n//\n", timep);
	printf("#include \"http/http.h\"\n\n");
	printf("#if BLD_FEATURE_ROMFS\n");

	//
	//	Open each input file and compile
	//
	nFile = 0;
	while (fgets(fileBuf, sizeof(fileBuf), fp) != NULL) {
		if ((p = strchr(fileBuf, '\n')) || (p = strchr(fileBuf, '\r'))) {
			*p = '\0';
		}
		if (*fileBuf == '\0') {
			continue;
		}
		if (stat(fileBuf, &finfo) == 0 && finfo.st_mode & S_IFDIR) {
			continue;
		} 
		if ((fd = open(fileBuf, O_RDONLY | O_BINARY, 0666)) < 0) {
			fprintf(stderr, "Can't open file %s\n", fileBuf);
			return -1;
		}
		printf("static uchar _file_%d[] = {\n", nFile);

		while ((len = read(fd, buf, sizeof(buf))) > 0) {
			p = buf;
			for (i = 0; i < len; ) {
				printf("    ");
				for (j = 0; p < &buf[len] && j < 16; j++, p++) {
					printf("%3d,", (unsigned char) *p);
				}
				i += j;
				printf("\n");
			}
		}
		printf("    0 };\n\n");

		close(fd);
		nFile++;
	}
	fclose(fp);

	//
	//	Now output the page index
	// 
	printf("MaRomInode %s[] = {\n", romName);

	if ((fp = fopen(files, "r" MPR_TEXT)) == NULL) {
		fprintf(stderr, "Can't open file list %s\n", files);
		return -1;
	}
	nFile = 0;
	while (fgets(fileBuf, sizeof(fileBuf), fp) != NULL) {
		if ((p = strchr(fileBuf, '\n')) || (p = strchr(fileBuf, '\r'))) {
			*p = '\0';
		}
		if (*fileBuf == '\0') {
			continue;
		}
		//
		//	Replace the prefix with a leading "/"
		// 
		if (strncmp(fileBuf, prefix, strlen(prefix)) == 0) {
			cp = &fileBuf[strlen(prefix)];
		} else {
			cp = fileBuf;
		}
		while((sl = strchr(fileBuf, '\\')) != NULL) {
			*sl = '/';
		}
		if (*cp == '/') {
			cp++;
		}

		if (*cp == '.' && cp[1] == '\0') {
			cp++;
		}
		if (stat(fileBuf, &finfo) == 0 && finfo.st_mode & S_IFDIR) {
			printf("    { \"%s\", 0, 0, 0 },\n", cp);
			continue;
		}
		printf("    { \"%s\", _file_%d, %d, %d },\n", cp, nFile, 
			(int) finfo.st_size, nFile);
		nFile++;
	}
	fclose(fp); 
	
	printf("    { 0, 0, 0 },\n");
	printf("};\n");
	printf("#endif // BLD_FEATURE_ROMFS\n");

	return 0;
}

////////////////////////////////////////////////////////////////////////////////

//
// Local variables:
// tab-width: 4
// c-basic-offset: 4
// End:
// vim: sw=4 ts=4 
//
